home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / ams__l~1.zoo / src / fastfont.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-05  |  4.7 KB  |  252 lines

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  This file is part of the Atari Machine Specific Library,
  4. //  and is Copyright 1992 by Warwick W. Allison.
  5. //
  6. //  You are free to copy and modify these sources, provided you acknowledge
  7. //  the origin by retaining this notice, and adhere to the conditions
  8. //  described in the file COPYING.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11.  
  12. #include "FastFont.h"
  13. #include "DoubleBuffer.h"
  14. #include <stdio.h>
  15.  
  16. unsigned long* CalcPos(Screen& s, int x, int y, short& shift)
  17. {
  18.     Resolution& rez=s.Rez();
  19.     shift=x&15;
  20.     return (unsigned long*)((short*)s.Location()+y*rez.BytesPerLine()/sizeof(short)+(x>>4)*rez.BitPlanes());
  21. }
  22.  
  23. FastFont::FastFont(Screen& s, int w, int h, char from, char to) :
  24.     min(from), max(to),
  25.     data(new unsigned short*[to-from+1]),
  26.     width(new unsigned short[to-from+1]),
  27.     height(h),
  28.     plane(0),
  29.     space(1)
  30. {
  31.     unsigned short mask=0;
  32.     for (int ww=w; ww; ww--) mask=(mask>>1)|0x8000;
  33.  
  34.     int x=0;
  35.     int y=0;
  36.     int LPL=s.Rez().BytesPerLine()/4;
  37.     for (int i=0; i<=to-from; i++) {
  38.         data[i]=new unsigned short[h];
  39.         short sh;
  40.         unsigned long* ptr=CalcPos(s,x,y,sh);
  41.         unsigned short m=0;
  42.         for (int j=0; j<height; j++) {
  43.             data[i][j]=((*ptr<<sh)>>16)&mask;
  44.             m|=data[i][j];
  45.             ptr+=LPL;
  46.         }
  47.  
  48.         int ww=0;
  49.         while (m) {
  50.             m<<=1;
  51.             ww++;
  52.         }
  53.  
  54.         if (!ww) ww=w/2; // For blank characters (eg. space!)
  55.  
  56.         width[i]=ww;
  57.  
  58.         x+=w;
  59.         if (x>=s.Rez().Width()) {
  60.             x=0;
  61.             y+=height;
  62.         }
  63.     }
  64. }
  65.  
  66. FastFont::FastFont(const char* f)
  67. {
  68.     data=0;
  69.  
  70.     FILE* fd=fopen(f,"rb");
  71.  
  72.     if (!fd) return;
  73.  
  74.     if (1!=fread(&min,sizeof(min),1,fd)) return;
  75.     if (1!=fread(&max,sizeof(max),1,fd)) return;
  76.     if (1!=fread(&height,sizeof(height),1,fd)) return;
  77.     if (1!=fread(&plane,sizeof(plane),1,fd)) return;
  78.     if (1!=fread(&space,sizeof(space),1,fd)) return;
  79.  
  80.     width=new unsigned short[max-min+1];
  81.     if (max-min+1!=fread(width,sizeof(width[0]),max-min+1,fd)) {
  82.         delete width;
  83.         return;
  84.     }
  85.  
  86.     data=new unsigned short*[max-min+1];
  87.  
  88.     for (int i=0; i<=max-min; i++) {
  89.         data[i]=new unsigned short[height];
  90.         if (height!=fread(data[i],sizeof(data[0][0]),height,fd)) {
  91.             delete width;
  92.             for (int j=0; j<=i; j++) delete data[j];
  93.             delete data;
  94.             data=0;
  95.             return;
  96.         }
  97.     }
  98.  
  99.     if (EOF==fclose(fd)) {
  100.         delete width;
  101.         for (int j=0; j<=max-min; j++) delete data[j];
  102.         delete data;
  103.         data=0;
  104.     }
  105. }
  106.  
  107. FastFont::~FastFont()
  108. {
  109.     delete width;
  110.     for (int j=0; j<=max-min; j++) delete data[j];
  111.     delete data;
  112. }
  113.  
  114. int FastFont::operator! ()
  115. {
  116.     return !data;
  117. }
  118.  
  119.  
  120. int FastFont::Save(const char* f)
  121. {
  122.     FILE* fd=fopen(f,"wb");
  123.  
  124.     if (!fd) return 0;
  125.  
  126.     if (1!=fwrite(&min,sizeof(min),1,fd)) return 0;
  127.     if (1!=fwrite(&max,sizeof(max),1,fd)) return 0;
  128.     if (1!=fwrite(&height,sizeof(height),1,fd)) return 0;
  129.     if (1!=fwrite(&plane,sizeof(plane),1,fd)) return 0;
  130.     if (1!=fwrite(&space,sizeof(space),1,fd)) return 0;
  131.     if (max-min+1!=fwrite(width,sizeof(width[0]),max-min+1,fd)) return 0;
  132.  
  133.     for (int i=0; i<=max-min; i++) {
  134.         if (height!=fwrite(data[i],sizeof(data[0][0]),height,fd)) return 0;
  135.     }
  136.  
  137.     return EOF!=fclose(fd);
  138. }
  139.  
  140. void FastFont::Plane(short p)
  141. {
  142.     plane=p;
  143. }
  144.  
  145. void FastFont::Put(char ch, int& x, int y)
  146. {
  147.     ch=(ch>=min && ch<=max) ? ch-min : 0;
  148.  
  149.     short BP=Pages->Current().Rez().BitPlanes();
  150.     short sh;
  151.     unsigned long* ptr=CalcPos(Pages->Current(),x,y,sh);
  152.     x+=width[ch];
  153.  
  154.     asm("
  155.             lsrw    #1,%5
  156.             addl    %5,%1
  157.             eorw    #15,%2
  158.         0:
  159.             clrl    d0
  160.             movew    %0@+,d0
  161.             lsll    %2,d0
  162.             eorw    d0,%1@(%6:w)
  163.             swap    d0
  164.             eorw    d0,%1@
  165.             addl    %3,%1
  166.             dbra    %4,0b
  167.  
  168.         " : // No outputs
  169.           :    "a" (data[ch]),
  170.             "a" (ptr),
  171.             "d" (sh),
  172.             "d" (Pages->Current().Rez().BytesPerLine()),
  173.             "d" (height-1),
  174.             "d" (plane),
  175.             "d" (BP*2)
  176.           : "d0"
  177.     );
  178. }
  179.  
  180. void FastFont::Put(const char* s, int& x, int y)
  181. {
  182.     //The simple approach... *** MUCH SLOWER - 24:86 ***
  183.     //while (*s) { Put(*s++,x,y); x+=space; }
  184.  
  185.     int BPL=Pages->Current().Rez().BytesPerLine();
  186.     short BP=Pages->Current().Rez().BitPlanes();
  187.     short BP2=BP*2;
  188.  
  189.     short sh;
  190.     short hm1=height-1;
  191.     unsigned short* ptr=(unsigned short*)CalcPos(Pages->Current(),x,y,sh)+plane;
  192.     sh^=15;
  193.  
  194.     while (*s) {
  195.         char ch=(*s>=min && *s<=max) ? *s-min : 0;
  196.  
  197.         asm("
  198.                 movel    %1,a0
  199.                 movel    %4,d1
  200.             0:
  201.                 clrl    d0
  202.                 movew    %0@+,d0
  203.                 lsll    %2,d0
  204.                 eorw    d0,a0@(%5:w)
  205.                 swap    d0
  206.                 eorw    d0,a0@
  207.                 addl    %3,a0
  208.                 dbra    %4,0b
  209.  
  210.             " : // No outputs
  211.               :    "a" (data[ch]),
  212.                 "a" (ptr),
  213.                 "d" (sh),
  214.                 "d" (BPL),
  215.                 "d" (hm1),
  216.                 "d" (BP2)
  217.               : "d0", "d1", "a0"
  218.         );
  219.  
  220.         short w=width[ch]+space;
  221.         x+=w;
  222.         sh-=w;
  223.         if (sh<0) {
  224.             sh+=16;
  225.             ptr+=BP;
  226.         }
  227.         s++;
  228.     }
  229. }
  230.  
  231. short FastFont::Width(char ch)
  232. {
  233.     ch=(ch>=min && ch<=max) ? ch-min : 0;
  234.     return width[ch];
  235. }
  236.  
  237. int FastFont::Width(const char* s)
  238. {
  239.     int w=0;
  240.     while (*s) {
  241.         char ch=(*s>=min && *s<=max) ? *s-min : 0;
  242.         w+=width[ch]+space;
  243.         s++;
  244.     }
  245.     return w;
  246. }
  247.  
  248. void FastFont::SetSpacing(short s)
  249. {
  250.     space=s;
  251. }
  252.